`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    11:24:17 12/02/2020 
// Design Name: 
// Module Name:    TDecoder 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
include "defines.v";

module TDecoder(
    input [31:0]instruction,
    output reg [4:0] useAddress1,
    output reg [2:0] Tuse1,
    output reg [4:0] useAddress2,
    output reg [2:0] Tuse2,
	 output reg [4:0] newAddress,
    output reg [2:0] Tnew
    );
	wire [4:0]rs, rt, rd;
	wire [5:0]opCode,func;
	 instructionSplitter splitter(
		.instruction(instruction),
		.rs(rs),
		.rt(rt),
		.rd(rd),
		.opCode(opCode),
		.func(func)
	 );
	 
	always @*
	begin
		case (opCode)
		
			`special:
				case (func)
					`addu:
					begin
						useAddress1	<=	rs;
						Tuse1	<=	1;
						useAddress2	<=	rt;
						Tuse2	<=	1;
						newAddress	<=	rd;
						Tnew	<=	1;
					end
					
					`subu:
					begin
						useAddress1	<=	rs;
						Tuse1	<=	1;
						useAddress2	<=	rt;
						Tuse2	<=	1;
						newAddress	<=	rd;
						Tnew	<=	1;
					end
					
					`jr:
					begin
						useAddress1	<=	rs;
						Tuse1	<=	0;
						useAddress2	<=	0;
						Tuse2	<=	`notUse;
						newAddress	<=	0;
						Tnew	<=	0;
					end
					
					`jalr:
					begin
						useAddress1	<=	rs;
						Tuse1	<=	0;
						useAddress2	<=	0;
						Tuse2	<=	`notUse;
						newAddress	<=	rd;
						Tnew	<=	0;
					end
					
					default:
					begin
						useAddress1	<=	0;
						Tuse1	<=	`notUse;
						useAddress2	<=	0;
						Tuse2	<=	`notUse;
						newAddress	<=	0;
						Tnew	<=	0;
					end
				endcase
			
			`ori:
			begin
				useAddress1	<=	rs;
				Tuse1	<=	1;
				useAddress2	<=	0;
				Tuse2	<=	`notUse;
				newAddress	<=	rt;
				Tnew	<=	1;
			end
			
			`addi:
			begin
				useAddress1	<=	rs;
				Tuse1	<=	1;
				useAddress2	<=	0;
				Tuse2	<=	`notUse;
				newAddress	<=	rt;
				Tnew	<=	1;
			end
			
			`lw:
			begin
				useAddress1	<=	rs;
				Tuse1	<=	1;
				useAddress2	<=	0;
				Tuse2	<=	`notUse;
				newAddress	<=	rt;
				Tnew	<=	2;
			end
			
			`sw:
			begin
				useAddress1	<=	rs;
				Tuse1	<=	1;
				useAddress2	<=	rt;
				Tuse2	<=	2;
				newAddress	<=	0;
				Tnew	<=	0;
			end
			
			`beq:
			begin
				useAddress1	<=	rs;
				Tuse1	<=	0;
				useAddress2	<=	rt;
				Tuse2	<=	0;
				newAddress	<=	0;
				Tnew	<=	0;
			end
			
			`lui:
			begin
				useAddress1	<=	rs;
				Tuse1	<=	1;
				useAddress2	<=	0;
				Tuse2	<=	`notUse;
				newAddress	<=	rt;
				Tnew	<=	1;
			end
			
			`jal:
			begin
				useAddress1	<=	0;
				Tuse1	<=	`notUse;
				useAddress2	<=	0;
				Tuse2	<=	`notUse;
				newAddress	<=	31;
				Tnew	<=	0;
			end
			
			`j:
			begin
				useAddress1	<=	0;
				Tuse1	<=	`notUse;
				useAddress2	<=	0;
				Tuse2	<=	`notUse;
				newAddress	<=	0;
				Tnew	<=	0;
			end
			
			default:
			begin
				useAddress1	<=	0;
				Tuse1	<=	`notUse;
				useAddress2	<=	0;
				Tuse2	<=	`notUse;
				newAddress	<=	0;
				Tnew	<=	0;
			end
		endcase
	end
	
endmodule
